package com.zoe.onelink.auth.serializer;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.TokenRequest;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-03-28 10:29
 */
public class OAuth2RequestSerializer implements ObjectDeserializer {

    @Override
    public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
        if (type == OAuth2Request.class) {
            JSONObject jsonObject = parser.parseObject();
            return (T) parseOAuth2Request(jsonObject);
        }
        return null;
    }

    @Override
    public int getFastMatchToken() {
        return 0;
    }


    private OAuth2Request parseOAuth2Request(JSONObject jsonObject) {
        Map<String, String> requestParameters = jsonObject.getObject("requestParameters", Map.class);
        String clientId = jsonObject.getString("clientId");
        String grantType = jsonObject.getString("grantType");
        String redirectUri = jsonObject.getString("redirectUri");
        Boolean approved = jsonObject.getBoolean("approved");
        Set<String> responseTypes = jsonObject.getObject("responseTypes", new TypeReference<HashSet<String>>() {});
        Set<String> scope = jsonObject.getObject("scope", new TypeReference<HashSet<String>>() {});
        Set<String> authorities = jsonObject.getObject("authorities", new TypeReference<HashSet<String>>() {});
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>(0);
        if (authorities != null && !authorities.isEmpty()) {
            authorities.forEach(s -> grantedAuthorities.add(new SimpleGrantedAuthority(s)));
        }
        Set<String> resourceIds = jsonObject.getObject("resourceIds", new TypeReference<HashSet<String>>() {});
        Map<String, Serializable> extensions = jsonObject.getObject("extensions", new TypeReference<HashMap<String, Serializable>>() {});

        OAuth2Request request = new OAuth2Request(requestParameters, clientId,
                grantedAuthorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions);
        TokenRequest tokenRequest = new TokenRequest(requestParameters, clientId, scope, grantType);
        request.refresh(tokenRequest);
        return request;
    }
}
